/*
 * JPanel.java
 *
 * Created on 19 June 2005, 01:41
 */

package org.owasp.webscarab.plugin.search.swing;

import java.util.Date;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.Action;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableModel;

import org.owasp.webscarab.model.ConversationID;
import org.owasp.webscarab.model.ConversationModel;
import org.owasp.webscarab.plugin.search.Search;
import org.owasp.webscarab.plugin.search.SearchModel;
import org.owasp.webscarab.ui.swing.ColumnWidthTracker;
import org.owasp.webscarab.ui.swing.ConversationTableModel;
import org.owasp.webscarab.ui.swing.ShowConversationAction;
import org.owasp.webscarab.ui.swing.SwingPluginUI;
import org.owasp.webscarab.ui.swing.DateRenderer;
import org.owasp.webscarab.util.swing.ColumnDataModel;
import org.owasp.webscarab.util.swing.SwingWorker;
import org.owasp.webscarab.util.swing.TableSorter;

/**
 *
 * @author  rogan
 */
public class SearchPanel extends JPanel implements SwingPluginUI {
    
    /**
	 * 
	 */
	private static final long serialVersionUID = -594313478603602953L;
	private Search _search;
    private SearchModel _model;
    private ConversationModel _conversationModel;
    private DefaultComboBoxModel _searches = new DefaultComboBoxModel();
    private ShowConversationAction _showConversationAction;
    private TableSorter _conversationSorter;
    
    /** Creates new form JPanel */
    public SearchPanel(Search search) {
        _search = search;
        _model = search.getModel();
        _conversationModel = _model.getConversationModel();
        initComponents();
        searchList.setModel(_searches);
        searchComboBox.setModel(_searches);
        _model.addPropertyChangeListener(new Listener());
        searchList.addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent evt) {
                Object selected = searchList.getSelectedValue();
                String description = "";
                String expression = "";
                if (selected != null) {
                    description = (String) selected;
                    expression = _model.getSearchExpression(description);
                }
                descriptionTextField.setText(description);
                expressionTextArea.setText(expression);
            }
        });
        
        TableModel tm = new ConversationTableModel(_conversationModel);
        _conversationSorter = new TableSorter(tm, conversationTable.getTableHeader());
        conversationTable.setModel(_conversationSorter);
        conversationTable.setDefaultRenderer(Date.class, new DateRenderer());
        
        ColumnWidthTracker.getTracker("ConversationTable").addTable(conversationTable);
        _showConversationAction = new ShowConversationAction(_model.getConversationModel());
        conversationTable.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1) {
                    int row = conversationTable.getSelectedRow();
                    row = _conversationSorter.modelIndex(row);
                    if (row >-1) {
                        ConversationID id = _conversationModel.getConversationAt(row);
                        _showConversationAction.putValue("CONVERSATION", id);
                        ActionEvent evt = new ActionEvent(conversationTable, 0, (String) _showConversationAction.getValue(Action.ACTION_COMMAND_KEY));
                        _showConversationAction.actionPerformed(evt);
                    }
                }
            }
        });
        
        updateSearches();
    }
    
    private void updateSearches() {
        _searches.removeAllElements();
        String[] searches = _model.getSearches();
        for (int i=0; i<searches.length; i++) {
            _searches.addElement(searches[i]);
        }
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {//GEN-BEGIN:initComponents
        java.awt.GridBagConstraints gridBagConstraints;

        jSplitPane1 = new javax.swing.JSplitPane();
        searchPanel = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        jScrollPane3 = new javax.swing.JScrollPane();
        searchList = new javax.swing.JList();
        jLabel1 = new javax.swing.JLabel();
        descriptionTextField = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        jScrollPane4 = new javax.swing.JScrollPane();
        expressionTextArea = new javax.swing.JTextArea();
        jPanel3 = new javax.swing.JPanel();
        addButton = new javax.swing.JButton();
        deleteButton = new javax.swing.JButton();
        reloadButton = new javax.swing.JButton();
        resultsPanel = new javax.swing.JPanel();
        searchComboBox = new javax.swing.JComboBox();
        conversationScrollPane = new javax.swing.JScrollPane();
        conversationTable = new javax.swing.JTable();

        setLayout(new java.awt.BorderLayout());

        jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
        jSplitPane1.setOneTouchExpandable(true);
        searchPanel.setLayout(new java.awt.GridBagLayout());

        jLabel2.setText("Searches");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        searchPanel.add(jLabel2, gridBagConstraints);

        jScrollPane3.setPreferredSize(new java.awt.Dimension(0, 0));
        searchList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        jScrollPane3.setViewportView(searchList);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.2;
        gridBagConstraints.weighty = 1.0;
        searchPanel.add(jScrollPane3, gridBagConstraints);

        jLabel1.setText("Description");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        searchPanel.add(jLabel1, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        searchPanel.add(descriptionTextField, gridBagConstraints);

        jLabel3.setText("Search Expression");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        searchPanel.add(jLabel3, gridBagConstraints);

        jScrollPane4.setMinimumSize(new java.awt.Dimension(22, 44));
        jScrollPane4.setPreferredSize(new java.awt.Dimension(0, 0));
        jScrollPane4.setViewportView(expressionTextArea);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.8;
        gridBagConstraints.weighty = 0.5;
        searchPanel.add(jScrollPane4, gridBagConstraints);

        jPanel3.setLayout(new java.awt.GridLayout(1, 0));

        addButton.setText("Add");
        addButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addButtonActionPerformed(evt);
            }
        });

        jPanel3.add(addButton);

        deleteButton.setText("Delete");
        deleteButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deleteButtonActionPerformed(evt);
            }
        });

        jPanel3.add(deleteButton);

        reloadButton.setText("Reload");
        reloadButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                reloadButtonActionPerformed(evt);
            }
        });

        jPanel3.add(reloadButton);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 4;
        searchPanel.add(jPanel3, gridBagConstraints);

        jSplitPane1.setLeftComponent(searchPanel);

        resultsPanel.setLayout(new java.awt.BorderLayout());

        searchComboBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                searchComboBoxActionPerformed(evt);
            }
        });

        resultsPanel.add(searchComboBox, java.awt.BorderLayout.NORTH);

        conversationTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {

            }
        ));
        conversationTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
        conversationScrollPane.setViewportView(conversationTable);

        resultsPanel.add(conversationScrollPane, java.awt.BorderLayout.CENTER);

        jSplitPane1.setRightComponent(resultsPanel);

        add(jSplitPane1, java.awt.BorderLayout.CENTER);

    }//GEN-END:initComponents
    
    private void searchComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchComboBoxActionPerformed
        Object selected = searchComboBox.getSelectedItem();
        if (selected != null) {
            String description = (String) selected;
            _search.setFilter(description);
        }
    }//GEN-LAST:event_searchComboBoxActionPerformed
    
    private void reloadButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_reloadButtonActionPerformed
        Object selected = searchList.getSelectedValue();
        if (selected != null) {
            final String description = (String) selected;
            reload(description);
        }
    }//GEN-LAST:event_reloadButtonActionPerformed
    
    private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteButtonActionPerformed
        Object selected = searchList.getSelectedValue();
        if (selected != null) {
            String description = (String) selected;
            _search.removeSearch(description);
        }
    }//GEN-LAST:event_deleteButtonActionPerformed
    
    private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed
        String description = descriptionTextField.getText();
        String expression = expressionTextArea.getText();
        if (!description.equals("") && !expression.equals("")) {
            _search.addSearch(description, expression);
            reload(description);
            searchList.setSelectedValue(description, true);
            searchComboBox.setSelectedItem(description);
        }
    }//GEN-LAST:event_addButtonActionPerformed
    
    private void reload(final String description) {
        addButton.setEnabled(false);
        deleteButton.setEnabled(false);
        reloadButton.setEnabled(false);
        SwingWorker worker = new SwingWorker() {
            public Object construct() {
                System.err.println("Reloading " + description);
                _search.reload(description);
                return null;
            }
            public void finished() {
                addButton.setEnabled(true);
                deleteButton.setEnabled(true);
                reloadButton.setEnabled(true);
            }
        };
        worker.start();
    }
    
    public Action[] getConversationActions() {
        return new Action[0];
    }
    
    public ColumnDataModel[] getConversationColumns() {
        return new ColumnDataModel[0];
    }
    
    public JPanel getPanel() {
        return this;
    }
    
    public String getPluginName() {
        return _search.getPluginName();
    }
    
    public Action[] getUrlActions() {
        return new Action[0];
    }
    
    public ColumnDataModel[] getUrlColumns() {
        return new ColumnDataModel[0];
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addButton;
    private javax.swing.JScrollPane conversationScrollPane;
    private javax.swing.JTable conversationTable;
    private javax.swing.JButton deleteButton;
    private javax.swing.JTextField descriptionTextField;
    private javax.swing.JTextArea expressionTextArea;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JScrollPane jScrollPane4;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JButton reloadButton;
    private javax.swing.JPanel resultsPanel;
    private javax.swing.JComboBox searchComboBox;
    private javax.swing.JList searchList;
    private javax.swing.JPanel searchPanel;
    // End of variables declaration//GEN-END:variables
    
    private class Listener implements PropertyChangeListener {
        
        public void propertyChange(PropertyChangeEvent evt) {
            if (evt.getPropertyName().equals(SearchModel.PROPERTY_SEARCHES)) {
                Runnable runner = new Runnable() {
                    public void run() {
                        updateSearches();
                    }
                };
                runOnEDT(runner);
            }
        }
        
        private void runOnEDT(Runnable runner) {
            try {
                if (!SwingUtilities.isEventDispatchThread()) {
                    SwingUtilities.invokeAndWait(runner);
                } else {
                    runner.run();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
}
